/*************************************************************************************************
    文 件 名：globle.c
    代码作者：DeffPuzzL、liujie
    编写版本：V3.0.0.0 
    创建日期：2016-07-14
    功能描述：cts系统接入
 *************************************************************************************************/
#include    "face.h"

/*************************************************************************************************
    交易全局变量申明
 *************************************************************************************************/
xmlDocPtr        g_pDoc = NULL;                                /*    XML解析句柄 */
SATInit          g_stInit = {0};
HCMIE			 g_hCme = {0};

/*************************************************************************************************
    函 数 名：pGetDoc()
    功能描述：获取XML句柄
    返回说明：
        void*            --结果指针地址
 *************************************************************************************************/
void*    pGetDoc()
{
    return g_pDoc;
}

/*************************************************************************************************
    函 数 名：pGetGloble                
    功能描述：获取当前交易全局信息
    返回说明：
        void*           --返回保存的起始地址    
 *************************************************************************************************/
HHCMIE   pGetCmie()
{
	return &g_hCme;
}

/*************************************************************************************************
    函 数 名：pGetGloble                
    功能描述：获取当前交易全局信息
    返回说明：
        void*           --返回保存的起始地址    
 *************************************************************************************************/
HHCMIE   pMallocCmie()
{
	return (HHCMIE)calloc(sizeof(HCMIE), 1);
}

/*************************************************************************************************
    函 数 名：pGetGloble                
    功能描述：获取当前交易全局信息
    返回说明：
        void*           --返回保存的起始地址    
 *************************************************************************************************/
GCts*   pGetGloble()
{
    return &g_hCme.m_stCts;
}

/*************************************************************************************************
    函 数 名：pGetGloble                
    功能描述：获取当前交易全局信息
    返回说明：
        void*           --返回保存的起始地址    
 *************************************************************************************************/
GCts*   pBksGloble()
{
    return &g_hCme.m_stBks;
}
/**************************************************************************************************
    函 数 名：pGetPool()
    功能描述：获取当前交易全局信息
    返回说明：
        void*            --结果指针地址
 **************************************************************************************************/
CtsPool**  pGetPool()
{
    return &g_hCme.m_Roop;
}

CtsEvent*   pGetEvent()
{
    return &g_hCme.m_stEvent;
}

/**************************************************************************************************
    函 数 名：pCmiePool(HHCMIE)
    功能描述：获取当前交易全局信息
    返回说明：
        void*            --结果指针地址
 **************************************************************************************************/
CtsPool**  pCmiePool(HHCMIE me)
{
    return &me->m_Roop;
}

/*************************************************************************************************
    函 数 名：pCmieGloble                
    功能描述：获取当前交易全局信息
    返回说明：
        void*           --返回保存的起始地址    
 *************************************************************************************************/
GCts*   pCmieGloble(HHCMIE me)
{
    return &me->m_stCts;
}

/*************************************************************************************************
    函 数 名：pCmieEvent                
    功能描述：获取当前交易全局信息
    返回说明：
        void*           --返回保存的起始地址    
 *************************************************************************************************/
CtsEvent*  pCmieEvent(HHCMIE me)
{
    return &me->m_stEvent;
}

/*************************************************************************************************
    函 数 名：lGetStatus()
    功能描述：获取当前交易状态
    返回说明：
        m_lState            --返回交易成功标识
 *************************************************************************************************/
long    lGmtStatus(HHCMIE me)
{
    return pCmieGloble(me)->m_lState;
}

/**************************************************************************************************
    函 数 名：vFillTime(GCts *pstCts)
    功能描述：填充交易时间
    返回说明：
        RC_SUCC         --成功
        RC_FAIL         --失败
 **************************************************************************************************/
void    vFillTime(GCts *pstCts)
{
    struct  tm  *tm;

    pstCts->m_lInTime = lGetUnixTime();
    tm = localtime(&pstCts->m_lInTime);
    snprintf(pstCts->m_szTxDate, sizeof(pstCts->m_szTxDate), "%4d%02d%02d", tm->tm_year + 1900, 
        tm->tm_mon + 1, tm->tm_mday);
    snprintf(pstCts->m_szTxTime, sizeof(pstCts->m_szTxTime), "%02d%02d%02d", tm->tm_hour, 
        tm->tm_min, tm->tm_sec);
}

/**************************************************************************************************
    函 数 名：lInitAllSatvm()
    功能描述：初始化所有表相关信息
    返回说明：
        RC_SUCC         --成功
        RC_FAIL         --失败
 **************************************************************************************************/
long    lInitAllSatvm(SATvm *pstSavm)
{
    TIndex    *pstIndex = NULL;

    if(!bIsTvmBoot())    return RC_SUCC;

	pvSetVTData(NULL);
	vTvmHoldRelease(pstSavm);	//	对于重连，先关在连
    vTvmHoldConnect(pstSavm);
    return lInitSvCache(pstSavm);
}

/*************************************************************************************************
    函 数 名：vReseVTData()
    功能描述：获取
    返回说明：
        无
 *************************************************************************************************/
void	vResetVTData()
{
	pvSetVTData(NULL);
	vTblDisconnect((SATvm *)pGetSATvm(), CTS_PLAT_PARAM);
}

/*************************************************************************************************
    函 数 名：pvSetVTData(void *pv)
    功能描述：获取
    返回说明：
        无
 *************************************************************************************************/
void*    pvSetVTData(void *pv)
{
	g_stInit.m_pvtData = pv;
	return g_stInit.m_pvtData;
}

/*************************************************************************************************
    函 数 名：pGetVTData()
    功能描述：获取
    返回说明：
        无
 *************************************************************************************************/
void*    pGetVTData()
{
	return g_stInit.m_pvtData;
}

/*************************************************************************************************
    函 数 名：pGetBuffer()
    功能描述：获取二级缓存报文缓存空间
    返回说明：
        无
 *************************************************************************************************/
char*    pGetBuffer()
{
    static  int   i = 0;

    if(0 == i)
    {
        ++ i;
        IBPFree(g_stInit.m_pstBuffer);
        g_stInit.m_pstBuffer = (char *)calloc(lGetUserSize(), sizeof(char));
    }

    return g_stInit.m_pstBuffer;
}

/*************************************************************************************************
    函 数 名：vReleaseBuffer()
    功能描述：释放二级缓存报文缓存空间
    返回说明：
        无
 *************************************************************************************************/
void    vReleaseBuffer()
{
    IBPFree(g_stInit.m_pstBuffer);
}

/*************************************************************************************************
    函 数 名：vSetProgram(char *s)
    功能描述：设置当前运行程序名称
    返回说明：
        无
 *************************************************************************************************/
void    vSetProgram(char *s)
{
    strncpy(g_stInit.m_szPGName, s, sizeof(g_stInit.m_szPGName));
}

/*************************************************************************************************
    函 数 名：sGetProgram()
    功能描述：获取当前运行程序名称
    返回说明：
        g_stInit.m_szPGName    --当前程序名称        
 *************************************************************************************************/
char*    sGetProgram()
{
    return g_stInit.m_szPGName;
}

/*************************************************************************************************
    函 数 名：vSetLogSize(long lSize)
    功能描述：设置缺省日志大小
    返回说明：
        无
 *************************************************************************************************/
void    vLogSetSize(long lSize)
{
    if(lSize <= 0)    lSize = LOG_DEFAULT_SIZE;    
    g_stInit.m_lLogSize = lSize;
}

/*************************************************************************************************
    函 数 名：lLogGetSize()
    功能描述：获取日志备份大小
    返回说明：
        g_stInit.m_lLogSize    --当前日志备份大小
 *************************************************************************************************/
long    lLogGetSize()
{
    return g_stInit.m_lLogSize;
}

/*************************************************************************************************
    函 数 名：lGetInQueue
    功能描述：获取输入事件队列ID
    返回说明：
        RC_SUCC         --成功
        RC_FAIL         --失败
 *************************************************************************************************/
long    lGetInQueue()
{
    return g_stInit.m_lInQueue;
}

/*************************************************************************************************
    函 数 名：vSetInQueue(long lQid)
    功能描述：设置输入事件队列ID
    返回说明：
        无
 *************************************************************************************************/
void    vSetInQueue(long lQid)
{
    g_stInit.m_lInQueue = lQid;
}

/*************************************************************************************************
    函 数 名：vSetMaxQueue(long lMax)
    功能描述：设置发送事件最大消息个数
    返回说明：
        无
 *************************************************************************************************/
void    vSetMaxQueue(long lMax)
{
    g_stInit.m_lMaxQueue = lMax > 0 ? lMax : 1;
}

/*************************************************************************************************
    函 数 名：lGetMaxQueue()
    功能描述：获取队列事件最大支持个数
    返回说明：
        无
 *************************************************************************************************/
long    lGetMaxQueue()
{
    return g_stInit.m_lMaxQueue;
}

/*************************************************************************************************
    函 数 名：vSetMaxPid(long lMax)
    功能描述：设置发送事件最大消息个数
    返回说明：
        无
 *************************************************************************************************/
void    vSetMaxPid(long lMax)
{
#ifdef __x86_64__
    g_stInit.m_lMaxPid = lMax > 180000 ? lMax : 180000;
 #elif __i386__
    g_stInit.m_lMaxPid = lMax > 40000 ? lMax : 40000;
#endif
}

/*************************************************************************************************
    函 数 名：lGetMaxPid()
    功能描述：获取队列事件最大支持个数
    返回说明：
        无
 *************************************************************************************************/
long    lGetMaxPid()
{
    return g_stInit.m_lMaxPid;
}

/*************************************************************************************************
    函 数 名：vSetToPos(long lMax)
    功能描述：设置发送事件最大消息个数
    返回说明：
        无
 *************************************************************************************************/
void    vSetToPos(long lPos)
{
    g_stInit.m_lToPos = lPos >= 0 ? lPos : 0;
}

/*************************************************************************************************
    函 数 名：lGetToPos()
    功能描述：获取队列事件最大支持个数
    返回说明：
        无
 *************************************************************************************************/
long    lGetToPos()
{
    return g_stInit.m_lToPos;
}

/*************************************************************************************************
    函 数 名：vSetToPos(long lMax)
    功能描述：设置发送事件最大消息个数
    返回说明：
        无
 *************************************************************************************************/
void    vSetToNum(long lNum)
{
    g_stInit.m_lToNum = lNum >= 0 ? lNum : 0;
}

/*************************************************************************************************
    函 数 名：lGetToNum()
    功能描述：获取队列事件最大支持个数
    返回说明：
        无
 *************************************************************************************************/
long    lGetToNum()
{
    return g_stInit.m_lToNum;
}

/*************************************************************************************************
    函 数 名：lGetOutQueue()
    功能描述：获取输出事件队列ID
    返回说明：
        RC_SUCC         --成功
        RC_FAIL         --失败
 *************************************************************************************************/
long    lGetToQueue()
{
    return g_stInit.m_lToQueue; 
}

/*************************************************************************************************
    函 数 名：vSetOutQueue()
    功能描述：设置输出事件队列ID
    返回说明：
        无
 *************************************************************************************************/
void    vSetToQueue(long lQid)
{
    g_stInit.m_lToQueue = lQid;
}

/*************************************************************************************************
    函 数 名：vSetTrQueue()
    功能描述：获取交易队列id
    返回说明：
        无
 *************************************************************************************************/
void    vSetTrQueue(long lQid)
{
    g_stInit.m_lTrQueue = lQid;
}

/*************************************************************************************************
    函 数 名：lGetTrQueue()
    功能描述：获取交易队列id
    返回说明：
        无
 *************************************************************************************************/
long    lGetTrQueue()
{
    return g_stInit.m_lTrQueue;
}

/*************************************************************************************************
    函 数 名：vSetUserPool
    功能描述：设置变量池大小, 启动之后不允许修改
    返回说明：
        无
 *************************************************************************************************/
void    vSetUserSize(long lSize)
{
    g_stInit.m_lUserSize = lSize <= 0 ? 0 : lSize;
}

/*************************************************************************************************
    函 数 名：lGetUserSize()
    功能描述：设置变量池大小, 启动之后不允许修改
    返回说明：
        long    --获取当前运行池大小    
 *************************************************************************************************/
long    lGetUserSize()
{
    return g_stInit.m_lUserSize;
}

/*************************************************************************************************
    函 数 名：skGetSocket()
    功能描述：获取Socket套接字
    返回说明：
        m_skSock            --返回套接字
 *************************************************************************************************/
BSock    skGetSocket()
{
    return g_stInit.m_skSock;
}

/*************************************************************************************************
    函 数 名：vSetSocket()
    功能描述：设置Socket套接字
    返回说明：
        无
 *************************************************************************************************/
void    vSetSocket(BSock sk)
{
    g_stInit.m_skSock = sk;
}

/*************************************************************************************************
    函 数 名：sLogGetPath()
    功能描述：获取日志路径缓存
    返回说明：
        m_szPath            --日志路径
 *************************************************************************************************/
char*    sLogGetPath()
{
    return g_stInit.m_szPath;
}

/*************************************************************************************************
    函 数 名：vLogSetPath()
    功能描述：设置日志路径缓存
    返回说明：
        m_szPath            --日志路径
 *************************************************************************************************/
void    vLogSetPath()
{
    snprintf(g_stInit.m_szPath, sizeof(g_stInit.m_szPath), "%s/%s", getenv("LOG_FILE_PATH"), 
        sGetDate());

    snprintf(g_stInit.m_szBuss, sizeof(g_stInit.m_szBuss), "%s/%s", g_stInit.m_szPath,
        CTS_BUSS_LOG);

    if(RC_SUCC != mkdir(g_stInit.m_szPath, S_IRWXU | S_IRWXG))
    {
        if(EEXIST != errno)
        {
            fprintf(stderr, "创建日志路径(%s)失败, err:(%d)(%s)", g_stInit.m_szPath, errno,
                strerror(errno));
            return ;
        }
    }
}

/*************************************************************************************************
    函 数 名：lGetSysLevel(HHCMIE cm)
    功能描述：获取当前系统日志级别
    返回说明：
        m_lSysLevel    当前日期级别    
 *************************************************************************************************/
long    lGetSysMaster()
{
    return g_stInit.m_lMaster;
}

/*************************************************************************************************
    函 数 名：vSetSysMaster(long lNode)
    功能描述：获取当前管理部署节点编号
    返回说明：
        无
 *************************************************************************************************/
void	vSetSysMaster(long lNode)
{
	g_stInit.m_lMaster = lNode > 0 ? lNode : 0;
}

/*************************************************************************************************
    函 数 名：lGetSysLevel(HHCMIE cm)
    功能描述：获取当前系统日志级别
    返回说明：
        m_lSysLevel    当前日期级别    
 *************************************************************************************************/
long    lGetSysLevel(HHCMIE cm)
{
    return cm->m_lSysLevel;
}

/*************************************************************************************************
    函 数 名：vSetSysLevel
    功能描述：获取当前系统日志级别
    返回说明：
        无
 *************************************************************************************************/
void    vSetSysLevel(HHCMIE cm, long lLev)
{
    if(lLev > LOG_MOST)
        cm->m_lSysLevel = LOG_MOST;
    else if(lLev < 0)
        cm->m_lSysLevel = LOG_DETAIL;
    else
        cm->m_lSysLevel = lLev;
}

/*************************************************************************************************
    函 数 名：lGetLogLevle()
    功能描述：获取日志级别
    返回说明：
        m_lLogLev        --返回当前交易日志级别
 *************************************************************************************************/
long    lGetLogLevel()
{
    return pGetGloble()->m_lLogLev;
}

/*************************************************************************************************
    函 数 名：vSetLogLev    
    功能描述：设置日志级别
    返回说明：
        无
 *************************************************************************************************/
void    vSetLogLevel(long lLevl)
{
    pGetGloble()->m_lLogLev = lLevl;
}

/*************************************************************************************************
    函 数 名：vInitGloble                
    功能描述：初始化当前全局信息
    返回说明：
        无
 *************************************************************************************************/
void    vInitialGloble()
{
    memset(pGetGloble(), 0, sizeof(GCts));
}

/*************************************************************************************************
    函 数 名：vCtsStore()
    功能描述：交易结构备份
 *************************************************************************************************/
void    vCtsStore()
{
    memcpy(pBksGloble(), pGetGloble(), sizeof(GCts));
}

/*************************************************************************************************
    函 数 名：vCtsRestore()
    功能描述：交易结构恢复
 *************************************************************************************************/
void    vCtsRestore()
{
    memcpy(pBksGloble(), pGetGloble(), sizeof(GCts));
}

/*************************************************************************************************
    函 数 名：vSetError(GCts *pstCts, const char *pszRet, const char *f, ...)
    功能描述：设置交易失败
    返回说明：
        无
 *************************************************************************************************/
void    vSetError(GCts *pstCts, const char *pszRet, const char *f, ...)
{
	long       lRet;
    va_list    args;

    pstCts->m_lState = STATUS_ERR;
    strncpy(pstCts->m_szRetCode, pszRet, sizeof(pstCts->m_szRetCode));

    va_start(args, f);
    lRet = vsnprintf(pstCts->m_szRetMsg, sizeof(pstCts->m_szRetMsg), f, args);
    va_end(args);
	pstCts->m_szRetMsg[lRet] = 0x00;
}

/*************************************************************************************************
    函 数 名：vSetTrError
    功能描述：设置交易失败
    返回说明：
        无
 *************************************************************************************************/
void    vSetTrError(const char *pszRet, const char *f, ...)
{
	long       lRet;
    va_list    args;

    vSetRetCode(pszRet);
    vSetStatus(STATUS_ERR);
    va_start(args, f);
    lRet = vsnprintf(pGetGloble()->m_szRetMsg, sizeof(pGetGloble()->m_szRetMsg), f, args);
    va_end(args);

	pGetGloble()->m_szRetMsg[lRet] = 0x00;
}

/*************************************************************************************************
    函 数 名：lGetSeqNo                
    功能描述：获取当前交易流水号
    返回说明：
        m_lSeqNo        --返回当前交易的流水号
 *************************************************************************************************/
long    lGetSeqNo()
{
    return pGetGloble()->m_lSeqNo;
}

/*************************************************************************************************
    函 数 名：vSetSeqNo(long lSeqNo)
    功能描述：设置当前交易流水号
    返回说明：
        无
 *************************************************************************************************/
void    vSetSeqNo(long lSeqNo)
{
    pGetGloble()->m_lSeqNo = lSeqNo;
}

/*************************************************************************************************
    函 数 名：vSetInHost    
    功能描述：设置接入主机编号
    返回说明：
        无
 *************************************************************************************************/
void    vSetInHost(long lHost)
{
    pGetGloble()->m_lInHost = lHost;
}

/*************************************************************************************************
    函 数 名：lGetInHost    
    功能描述：取接入主机编号
    返回说明：
        m_lInHost        --返回交易接入的主机号
 *************************************************************************************************/
long    lGetInHost()
{
    return pGetGloble()->m_lInHost;
}

/*************************************************************************************************
    函 数 名：vSetLocalHost    
    功能描述：设置接入主机编号
    返回说明：
        无
 *************************************************************************************************/
void    vSetLocalHost(long lHost)
{
    pGetGloble()->m_lHost = lHost;
}

/*************************************************************************************************
    函 数 名：lGetLocalHost    
    功能描述：取接入主机编号
    返回说明：
        m_lHost        --返回当前接入的主机号
 *************************************************************************************************/
long    lGetLocalHost()
{
    return pGetGloble()->m_lHost;
}

/*************************************************************************************************
    函 数 名：sGetTrCode()
    功能描述：取服务码
    返回说明：
        m_szTrCode        --获取交易代码
 *************************************************************************************************/
char*    sGetTrCode()
{
    return pGetGloble()->m_szTrCode;
}

/*************************************************************************************************
    函 数 名：vSetTrCode(const char* pszCode)
    功能描述：设置服务码
    返回说明：
        无
 *************************************************************************************************/
void    vSetTrCode(const char* pszCode)
{
    memset(pGetGloble()->m_szTrCode, 0, sizeof(pGetGloble()->m_szTrCode));
    strncpy(pGetGloble()->m_szTrCode, pszCode, sizeof(pGetGloble()->m_szTrCode) - 1);
}

/*************************************************************************************************
    函 数 名：sGetInCode()
    功能描述：获取服务子码
    返回说明：
        m_szInCode            --返回接入交易码    
 *************************************************************************************************/
char*    sGetInCode(void)
{
    return pGetGloble()->m_szInCode;
}

/*************************************************************************************************
    函 数 名：vSetInCode(const char* pszInCode)
    功能描述：设置接入交易码
    返回说明：
        无
 *************************************************************************************************/
void    vSetInCode(const char* pszInCode)
{
    memset(pGetGloble()->m_szInCode, 0, sizeof(pGetGloble()->m_szInCode));
    strncpy(pGetGloble()->m_szInCode, pszInCode, sizeof(pGetGloble()->m_szInCode) - 1);
}

/*************************************************************************************************
    函 数 名：sGetInSubCode()
    功能描述：获取服务子码
    返回说明：
        m_szInCode            --返回接入交易码    
 *************************************************************************************************/
char*    sGetInSubCode(void)
{
    return pGetGloble()->m_szInSCode;
}

/*************************************************************************************************
    函 数 名：vSetSubCode()
    功能描述：设置服务子码
    返回说明：
        无
 *************************************************************************************************/
void    vSetInSubCode(const char* pszSubCode)
{
    memset(pGetGloble()->m_szInSCode, 0, sizeof(pGetGloble()->m_szInSCode));
    strncpy(pGetGloble()->m_szInSCode, pszSubCode, sizeof(pGetGloble()->m_szInSCode) - 1);
}

/*************************************************************************************************
    函 数 名：lGetStatus()
    功能描述：获取当前交易状态
    返回说明：
        m_lState            --返回交易成功标识
 *************************************************************************************************/
long    lGetStatus()
{
    return pGetGloble()->m_lState;
}

/*************************************************************************************************
    函 数 名：vSetStatus
    功能描述：设置当前交易状态
 *************************************************************************************************/
void    vSetStatus(long lState)
{
    pGetGloble()->m_lState = lState;
}

/*************************************************************************************************
    函 数 名：sGetRetCode
    功能描述：获取当前响应码
 *************************************************************************************************/
char*    sGetRetCode(void)
{
    return pGetGloble()->m_szRetCode;
}

/*************************************************************************************************
    函 数 名：vSetRetCode
    功能描述：设置当前响应码
 *************************************************************************************************/
void    vSetRetCode(const char* pszRetCode)
{
    strncpy(pGetGloble()->m_szRetCode, pszRetCode, sizeof(pGetGloble()->m_szRetCode) - 1);
}

/*************************************************************************************************
    函 数 名：sGetRetMsg
    功能描述：获取当前响应信息
 *************************************************************************************************/
char*    sGetRetMsg(void)
{
    return pGetGloble()->m_szRetMsg;
}

/*************************************************************************************************
    函 数 名：vSetRetMsg(const char* szFmt, ...)
    功能描述：设置当前响应信息
 *************************************************************************************************/
void    vSetRetMsg(const char* szFmt, ...)
{
	long	   lRet;
    va_list    args;

    va_start(args, szFmt);
    lRet = vsnprintf(pGetGloble()->m_szRetMsg, sizeof(pGetGloble()->m_szRetMsg), szFmt, args);
    va_end(args);
	pGetGloble()->m_szRetMsg[lRet] = 0x00;
}

/*************************************************************************************************
    函 数 名：lGetLastStatus
    功能描述：获取上次调用交易状态
 *************************************************************************************************/
long    lGetLastStatus(void)
{
    return pGetGloble()->m_lLastState;
}

/*************************************************************************************************
    函 数 名：vSetLastStatus
    功能描述：设置上次调用交易状态
 *************************************************************************************************/
void    vSetLastStatus(const long lStatus)
{
    pGetGloble()->m_lLastState = lStatus;
}

/*************************************************************************************************
    函 数 名：sGetLastRet
    功能描述：获取上次调用响应码
 *************************************************************************************************/
char*    sGetLastRet(void)
{
    return pGetGloble()->m_szLastRet;
}

/*************************************************************************************************
    函 数 名：vSetLastRet
    功能描述：设置上次调用响应码
 *************************************************************************************************/
void    vSetLastRet(const char* pszRetCode)
{
    strncpy(pGetGloble()->m_szLastRet, pszRetCode, sizeof(pGetGloble()->m_szLastRet) - 1);
}

/*************************************************************************************************
    函 数 名：vSetLastMsg
    功能描述：设置上次调用响应信息
 *************************************************************************************************/
void    vSetLastMsg(const char* pszFmt, ...)
{
	long       lRet;
    va_list    args;

    va_start(args, pszFmt);
    lRet = vsnprintf(pGetGloble()->m_szLastMsg, sizeof(pGetGloble()->m_szLastMsg), pszFmt, args);
    va_end(args);

	pGetGloble()->m_szLastMsg[lRet] = 0x00;
}

/*************************************************************************************************
    函 数 名：sGetLastError
    功能描述：获取上次调用响应信息
 *************************************************************************************************/
char*    sGetLastMsg(void)
{
    return pGetGloble()->m_szLastMsg;
}

/*************************************************************************************************
    函 数 名：sGetLogName
    功能描述：获取当前日志名
 *************************************************************************************************/
char*    sGetLogName()
{
    return pGetGloble()->m_szLogName;
}

/*************************************************************************************************
    函 数 名：sGetActDate()
    功能描述：获取当前清算日期
 *************************************************************************************************/
char*    sGetActDate()
{
    return pGetGloble()->m_szCrDate;
}

/*************************************************************************************************
    函 数 名：sGetTxDate
    功能描述：获取当前交易日期
 *************************************************************************************************/
char*    sGetTxDate()
{
    return pGetGloble()->m_szTxDate;
}

/*************************************************************************************************
    函 数 名：vSetLogName()
    功能描述：设置当前交易日志名
 *************************************************************************************************/
void    vSetLogName(const char* pszFmt, ...)
{
    long       lRet;
    va_list    args;

    va_start(args, pszFmt);
    lRet = vsnprintf(pGetGloble()->m_szLogName, sizeof(pGetGloble()->m_szLogName), pszFmt, args);
    va_end(args);

	pGetGloble()->m_szLogName[lRet] = 0x00;
}

/*************************************************************************************************
    函 数 名：vInitFileFd
    功能描述：调用组件时，初始化文件句柄
 *************************************************************************************************/
void    vInitFileFd(HHCMIE cm)
{
    FILE    *fp;

    if((fp = fopen(cm->m_szLog, "a+")) == NULL)
        return;

    g_stInit.m_fdChk = fileno(fp);
    fclose(fp);
}

/*************************************************************************************************
    函 数 名：vCheckFileFd
    功能描述：组件处理完毕，检查文件句柄是否关闭
 *************************************************************************************************/
void    vCheckFileFd(HHCMIE cm)
{
    int     fd;
    FILE    *fp;

    if((fp = fopen(cm->m_szLog, "a+")) == NULL)
        return;

    fd = fileno(fp);
    fclose(fp);
    if(0 == g_stInit.m_fdChk)
        g_stInit.m_fdChk = fd;
    else if(fd > g_stInit.m_fdChk)
    {
        IBTwarn(cm, "可能存在文件句柄(%d)(%d)未关闭", fd, g_stInit.m_fdChk);
        g_stInit.m_fdChk = fd;
    }

    return ;
}

/*************************************************************************************************
    函 数 名：lGetUseTime
    功能描述：获取该服务已用时间
 *************************************************************************************************/
long    lGetUseTime(void)
{
    return pGetGloble()->m_lUseTime;
}

/*************************************************************************************************
    函 数 名：lGetTimeout
    功能描述：< 0 则超时
 *************************************************************************************************/
long    lGetTimeout(void)
{
    return pGetGloble()->m_lTimeOut - (long)(lGetUnixTime() - pGetGloble()->m_lInTime);
}

/*************************************************************************************************
    函 数 名：vSetSuccess(GCts *pstCts)
    功能描述：取接入主机编号
 *************************************************************************************************/
void    vSetRetSucc(GCts *pstCts)
{
    pstCts->m_lState = STATUS_OK;
    strcpy(pstCts->m_szRetCode, RET_SUCCESS);
    strcpy(pstCts->m_szRetMsg, MSG_SUCCESS);
}

/*************************************************************************************************
    函 数 名：vSetSuccess(GlbCts *pstCts)
    功能描述：取接入主机编号
 *************************************************************************************************/
void    vSetSuccess(GCts *pstCts)
{
    pstCts->m_lState = STATUS_OK;
    strcpy(pstCts->m_szRetCode, RET_SUCCESS);
    strcpy(pstCts->m_szRetMsg, MSG_SUCCESS);
    pstCts->m_lLastState = STATUS_OK;
    strcpy(pstCts->m_szLastRet, RET_SUCCESS);
    strcpy(pstCts->m_szLastMsg, MSG_SUCCESS);
}

/*************************************************************************************************
    二级缓存
 *************************************************************************************************/
/*************************************************************************************************
    函 数 名：vLogStore()
    功能描述：日志备份
 *************************************************************************************************/
void    vLogStore(HHCMIE cm)
{
    cm->m_lSysLevBak = cm->m_lSysLevel;
    strncpy(cm->m_szBak, cm->m_szLog, sizeof(cm->m_szBak));
}

/*************************************************************************************************
    函 数 名：vLogRestore()
    功能描述：日志回复
 *************************************************************************************************/
void    vLogRestore(HHCMIE cm)
{
    cm->m_lSysLevel = cm->m_lSysLevBak;
    strncpy(cm->m_szLog, cm->m_szBak, sizeof(cm->m_szLog));
}

/*************************************************************************************************
    函 数 名：vLogSetName(const char* fmt, ...)
    功能描述：多线程编程时，设置自定义日志名称
 *************************************************************************************************/
void    vLogSetName(HHCMIE cm, const char* fmt, ...)
{
	long    lRet;
    va_list args;

    va_start(args, fmt);
    lRet = vsnprintf(cm->m_szLog, sizeof(cm->m_szLog), fmt, args);
    va_end(args);

	cm->m_szLog[lRet] = 0x00;
}

/*************************************************************************************************
    函 数 名：sLogGetBuss()
    功能描述：获取当前交易全局信息
 *************************************************************************************************/
char    *sLogGetBuss()
{
    if(0x00 == g_stInit.m_szBuss[0])
        strcpy(g_stInit.m_szBuss, CTS_BUSS_LOG);
    return g_stInit.m_szBuss;
}

/*************************************************************************************************
    函 数 名：vLogInitial(GCts *pstCts)
    功能描述：初始化交易日志名 
 *************************************************************************************************/
void    vLogInitial(HHCMIE cm, GCts *pstCts)
{
    vSetSysLevel(cm, pstCts->m_lLogLev);
    if(memcmp(g_stInit.m_szDate, pstCts->m_szTxDate, 8))
    {
        memcpy(g_stInit.m_szDate, pstCts->m_szTxDate, 8);
        sAlterPath(g_stInit.m_szPath, sizeof(g_stInit.m_szPath), pstCts->m_szTxDate);
        snprintf(g_stInit.m_szBuss, sizeof(g_stInit.m_szBuss), "%s/%s", g_stInit.m_szPath,
            CTS_BUSS_LOG);
    }

    if(0x00 == pstCts->m_szLogName[0])
        strcpy(pstCts->m_szLogName, DEFAULT_LOG);

    if(RC_SUCC == access(g_stInit.m_szPath, X_OK | W_OK))
    {
        snprintf(cm->m_szLog, sizeof(cm->m_szLog), "%s/%s", g_stInit.m_szPath, pstCts->m_szLogName);
        return ;
    }

    if(RC_SUCC != mkdir(g_stInit.m_szPath, S_IRWXU | S_IRWXG))
    {
        if(EEXIST != errno)
        {
            fprintf(stderr, "创建日志(%s)失败, (%s)", g_stInit.m_szPath, strerror(errno));
			strncpy(cm->m_szLog, pstCts->m_szLogName, sizeof(cm->m_szLog));
            return ;
        }
    }

    snprintf(cm->m_szLog, sizeof(cm->m_szLog), "%s/%s", g_stInit.m_szPath, 
        pstCts->m_szLogName);

    return ;
}

/*************************************************************************************************
    函 数 名：vWriteString(char *s, long l)
    功能描述：获取当前交易全局信息
 *************************************************************************************************/
void    vWriteString(HHCMIE cm, char *s, long l)
{
    FILE    *fp = NULL;

    if(!s) return ;

    if(NULL == (fp = fopen(cm->m_szLog, "a+")))
    {
        fprintf(stderr, "P(%d), 打开文件(%s)失败, err:%s,[%s]\n", getpid(), cm->m_szLog, 
            strerror(errno));
        return ;
    }

    fwrite(s, l, 1, fp);
    fwrite("\n", 1, 1, fp);
    fclose(fp);
}

/*************************************************************************************************
    函 数 名：vLogWriteList(GCts *pstCts)
    功能描述：交易结束时记录交易状况
 *************************************************************************************************/
void    vLogWriteList(GCts *pstCts)
{
    struct  stat st; 
    FILE    *fp = NULL;
    char    szBak[512];
    struct  timeb    tb;
    struct  tm       *ptm = NULL;

    if(NULL == (fp = fopen(sLogGetBuss(), "a+")))
    {
        fprintf(stderr, "P(%d), 打开文件(%s)失败, err:%s\n", getpid(), sLogGetBuss(), 
            strerror(errno));
        return ;
    }

    ftime(&tb);
    ptm = localtime(&tb.time);
    pstCts->m_lUseTime = tb.time - pstCts->m_lInTime;
    fprintf(fp, "P=%-5d N=%-6d D=%s B=%s %s E=%04d%02d%02d %02d%02d%02d:%03d C=%-3d T=%d >>%s,%s,%s\n", 
        getpid(), pstCts->m_lSeqNo, pstCts->m_szCrDate, pstCts->m_szTxDate, pstCts->m_szTxTime, 
        ptm->tm_year + 1900, ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec, 
        tb.millitm, pstCts->m_lUseTime, pstCts->m_lSType, pstCts->m_szTrCode, pstCts->m_szRetCode, 
        pstCts->m_szRetMsg);
    fclose(fp);

    if(0 == stat(sLogGetBuss(), &st) && st.st_size >= lLogGetSize())
    {
        snprintf(szBak, sizeof(szBak), "%s.%s", sLogGetBuss(), pstCts->m_szTxTime);
        rename(sLogGetBuss(), szBak);
    }
}

/*************************************************************************************************
    函 数 名：vFlushPLog(char *pszFile, long lLine, long lPid, long lLv)
    功能描述：获取当前交易全局信息
 *************************************************************************************************/
void    vPrintString(HHCMIE cm, const char *pszFile, long lLine, long lState, long lSeqNo, long lLv,
            const char *fmt, ...)
{
    va_list ap;
    long    lLen;
    struct  tm am;
    struct  timeb tb;
    FILE    *fp = NULL;
    char    szMsg[2048];

    if(lLv < lGetSysLevel(cm))
        return ;

	switch(lLv)
	{
    case LOG_WARM:
        lLen = strlen(strncpy(szMsg, "警告: ", sizeof(szMsg)));
		break;
    case LOG_ERROR:
        lLen = strlen(strncpy(szMsg, "错误: ", sizeof(szMsg)));
		break;
    case LOG_SYSTEM:
        lLen = strlen(strncpy(szMsg, "系统错误: ", sizeof(szMsg)));
		break;
    case LOG_DATABASE:
        lLen = strlen(strncpy(szMsg, "数据库错误: ", sizeof(szMsg)));
		break;
	default:
		lLen = 0;
		break;
	}

    va_start(ap, fmt);
    lLen += vsnprintf(szMsg + lLen, sizeof(szMsg) - lLen - 1, fmt, ap);
    va_end(ap);
	szMsg[lLen] = 0x00;

    ftime(&tb);
	localtime_r(&tb.time, &am);

    if(NULL == (fp = fopen(cm->m_szLog, "a+")))
    {
        fprintf(stderr, "P(%d), 打开文件(%s)失败, err:%s,[%s]\n", getpid(), 
            cm->m_szLog, strerror(errno), szMsg);
        return ;
    }

    if(0 == lState)    //  正常的trace
    {
        fprintf(fp, "F=%-16s L=%-5d P=%-7d N=%-6d T=%04d%02d%02d %02d%02d%02d:%03d  %s\n", 
            pszFile, lLine, getpid(), lSeqNo, am.tm_year + 1900, am.tm_mon + 1, 
            am.tm_mday, am.tm_hour, am.tm_min, am.tm_sec, tb.millitm, szMsg);
    }
    else
        fprintf(fp, "%s\n", szMsg);
    fclose(fp);
}

/*************************************************************************************************
    函 数 名：vPrintHexes(char *s, int k)
    功能描述：打印字符串的bcd码
 *************************************************************************************************/
void    vPrintHexes(HHCMIE cm, long lv, char *s, int k)
{
    register    int i, j, n = 0, a, len;
    char        szMsg[512];

    if(lv < lGetSysLevel(cm))
        return ;

    memset(szMsg, 0, sizeof(szMsg));
    for(i = 0, n = 0; i < k; n ++)
    {
        len = sprintf(szMsg, "%07d - %07d: ", n * 16, 
            (n + 1) * 16 - 1 > k - 1 ? k - 1 : (n + 1) * 16 - 1);
        for(j = 0, a = 0; j < 16; j ++,i++)
        {
            if(i < k)
            {
                len += sprintf(szMsg + len, "%02X ", (uchar)s[i]);
                ++ a;
            }
            else
            {
                len += sprintf(szMsg + len, "   ");
                i = k - 1;
            }
        }

        strcat(szMsg, " ");
        len ++;

        for(a; a > 0; a --)
        {
            if(32 <= (uchar)s[i - a] && s[i - a] <= 126)
                len += sprintf(szMsg + len, "%c", (uchar)s[i - a]);
            else
                len += sprintf(szMsg + len, ".");
        }
        szMsg[len] = 0x00;
        vPrintString(cm, NULL, 0, -1, 0, LOG_MOST, "%s", szMsg);
    }

    return ;
}

/**************************************************************************************************
    函 数 名：vPrint
    功能描述：自定义日志文件输出
    返回说明：
        void*            --结果指针地址
 **************************************************************************************************/
void    vPrint(char *pszLog, char *pszFile, long lLine, long lPid, long lSeqNo, char *fmt, ...)
{
    va_list ap;
    struct  stat st;
    FILE    *fp = NULL;
    long    nRet = 0, lSize;
    char    szLog[1024], szMsg[10240], szBak[1024], szDate[9];

    memset(szLog, 0, sizeof(szLog));
    snprintf(szLog, sizeof(szLog), "%s/%s/%s", getenv("LOG_FILE_PATH"),
        _sGetDate(szDate, sizeof(szDate)), pszLog);

    if(NULL == (fp = fopen(szLog, "a+")))
    {
        fprintf(stderr, "打开文件%s失败:[%s]", szLog, strerror(errno));
        return ;
    }

    fprintf(fp, "F=%-16s L=%-5d P=%-7d N=%-6d T=%s  ", pszFile, lLine, lPid, lSeqNo,
        sGetLogTime());

    memset(szMsg, 0, sizeof(szMsg));
    va_start(ap, fmt);
    vsnprintf(szMsg, sizeof(szMsg), fmt, ap);
    va_end(ap);

    strcat(szMsg, "\n");
    fprintf(fp, szMsg);
    fclose(fp);

    if(0 == stat(szLog, &st) && st.st_size >= lLogGetSize())
    {
        snprintf(szBak, sizeof(szBak), "%s.%s", szLog, sGetCurrentTime());
        rename(szLog, szBak);
    }
}

/*************************************************************************************************
    code end
 *************************************************************************************************/
